{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The perceptron algorithm is a type of linear classification algorithm used to classify data into two categories. It is a simple algorithm that learns from the mistakes made during the classification process and adjusts the weights of the input features to improve the accuracy of the classification. \n",
    "\n",
    "```python \n",
    "y_pred = sign(w0 + w1*x1 + w2*x2 + ... + wn*xn)\n",
    "wi = wi + learning_rate * (target - y_pred) * xi\n",
    "```\n",
    "\n",
    "Here is an implementation of the perceptron algorithm in Python:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "class Perceptron:\n",
    "    def __init__(self, lr=0.01, n_iter=100):\n",
    "        self.lr = lr\n",
    "        self.n_iter = n_iter\n",
    "\n",
    "    def fit(self, X, y):\n",
    "        self.weights = np.zeros(1 + X.shape[1])\n",
    "        self.errors = []\n",
    "\n",
    "        for _ in range(self.n_iter):\n",
    "            errors = 0\n",
    "            for xi, target in zip(X, y):\n",
    "                update = self.lr * (target - self.predict(xi))\n",
    "                self.weights[1:] += update * xi\n",
    "                self.weights[0] += update\n",
    "                errors += int(update != 0.0)\n",
    "            self.errors.append(errors)\n",
    "        return self\n",
    "\n",
    "    def net_input(self, X):\n",
    "        return np.dot(X, self.weights[1:]) + self.weights[0]\n",
    "\n",
    "    def predict(self, X):\n",
    "        return np.where(self.net_input(X) >= 0.0, 1, -1)\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Perceptron class has the following methods:\n",
    "\n",
    "__init__(self, lr=0.01, n_iter=100): Initializes the perceptron with a learning rate (lr) and number of iterations (n_iter) to perform during training.\n",
    "\n",
    "fit(self, X, y): Trains the perceptron on the input data X and target labels y. The method initializes the weights to zero and iterates through the data n_iter times, adjusting the weights after each misclassification. The method returns the trained perceptron.\n",
    "\n",
    "net_input(self, X): Computes the weighted sum of inputs and bias.\n",
    "\n",
    "predict(self, X): Predicts the class label for a given input X based on the current weights.\n",
    "\n",
    "To use the perceptron algorithm, you can create an instance of the Perceptron class, and then call the fit method with your input data X and target labels y. Here is an example usage:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1,  1])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = np.array([[2.0, 1.0], [3.0, 4.0], [4.0, 2.0], [3.0, 1.0]])\n",
    "y = np.array([-1, 1, 1, -1])\n",
    "perceptron = Perceptron()\n",
    "perceptron.fit(X, y)\n",
    "\n",
    "new_X = np.array([[5.0, 2.0], [1.0, 3.0]])\n",
    "perceptron.predict(new_X)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
